﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using FRW.Common.Extensions;

namespace FRW.Common
{
    public enum ApplicationInstallType
    {
        USER,
        SYSTEM
    }

    public delegate void DirectoryUpdatedDelegate(object sender, EventArgs ev);

    public sealed class PathManager
    {
        private static volatile PathManager instance;
        private static object syncRoot = new object();

        private string _applicationFolderPath;
        private string _dataFolderPath;
        private string _appName;

        public event DirectoryUpdatedDelegate DataFolderUpdated;
        public event DirectoryUpdatedDelegate ApplicationFolderUpdated;

        public string ApplicationFolder
        {
            get
            {
                if (_applicationFolderPath == null)
                {
                    SetType(ApplicationInstallType.SYSTEM);
                }
                return _applicationFolderPath;
            }
            set
            {
                _applicationFolderPath = value;
                if (ApplicationFolderUpdated != null)
                {
                    ApplicationFolderUpdated(this, new EventArgs());
                }
            }
        }

        /// <summary>
        /// Checks that all required paths are available and if not creates the paths.
        /// </summary>
        /// <returns>true - Initialisation completed without error.</returns>
        public bool Initialise()
        {
            if (!Directory.Exists(_applicationFolderPath))
            {
                Directory.CreateDirectory(_applicationFolderPath);
            }

            return true;
        }

        public string DataFolder
        {
            get { return _dataFolderPath; }
            set
            {
                _dataFolderPath = value;
                if (DataFolderUpdated != null)
                {
                    DataFolderUpdated(this, new EventArgs());
                }
            }
        }

        private PathManager()
        {
            _appName = System.Windows.Forms.Application.ProductName;
        }

        public static PathManager Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (syncRoot)
                    {
                        if (instance == null)
                            instance = new PathManager();
                    }
                }

                return instance;
            }
        }

        public bool UserFolderExists()
        {
            return true;
        }

        public bool SystemFolderExists()
        {
            return true;
        }

        public bool FolderExists()
        {
            return true;
        }

        public bool FolderExists(string folder)
        {
            return true;
        }

        public static string CreateTemporaryFolder()
        {
            string appName = System.Windows.Forms.Application.ProductName;
            string md5Name = appName.MD5();

            string newTemporaryFolder;

            do
            {
                newTemporaryFolder = Path.Combine(Path.GetTempPath() + md5Name + @"\" + Path.GetRandomFileName());
            } while (Directory.Exists(newTemporaryFolder));

            Directory.CreateDirectory(newTemporaryFolder);

            return newTemporaryFolder;
        }

        public static bool DeleteTemporaryFolder(string folderName)
        {
            bool directoryDeleted = false;

            try
            {
                // recursive delete of the supplied folder
                Directory.Delete(PathManager.Instance.DataFolder, true);
            }
            catch
            {
                // For now there is no error handling being implemented
            }

            return directoryDeleted;
        }

        public void CreateFolder()
        {
        }

        public void CreateFolder(string folder)
        {
        }

        public void SetType(ApplicationInstallType ait)
        {
            if (ait == ApplicationInstallType.SYSTEM)
            {
                _applicationFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\" + _appName;
            }
            else
            {
                _applicationFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\" + _appName;
            }

            if (!Directory.Exists(_applicationFolderPath))
            {
                Directory.CreateDirectory(_applicationFolderPath);
            }
        }

        public string GetApplicationFile(string fileName)
        {
            return _applicationFolderPath + @"\" + fileName;
        }

        public string GetDataFile(string fileName)
        {
            return _dataFolderPath + @"\" + fileName;
        }

        public string MyDocuments
        {
            get
            {
                return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            }
        }
    }
}
